package com.briup;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.alibaba.excel.metadata.data.CellData;
import com.alibaba.excel.metadata.data.ReadCellData;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.util.ConverterUtils;
import com.alibaba.excel.util.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 监听器：实现读操作
 * 1.将读取到的每行数据封装到list集合
 * 2.通过mapper对象保存到数据库
 * 3.程序分批插入保存数据，每批的大小和容量相同
 */
public class DemoDataListener implements ReadListener<DemoData> {
    private DemoDataMapper mapper;
    private int batchCount = 5;
    //使用工具类，1检查参数是否合法 控制参数合理性  初始容量大小  5+num+num/10
    private List<DemoData> list = ListUtils.newArrayListWithExpectedSize(batchCount);

    public DemoDataListener(DemoDataMapper mapper) {
        this.mapper = mapper;
    }

    public void invoke(DemoData data, AnalysisContext context) {
        //每次读取一行数据，自动调用该方法
        System.out.println("读取每行数据："+data);
        list.add(data);
        if(list.size() >= batchCount){
            //将50条数据分批保存到数据库
            saveData();
            //清空list。重新存储下一批数据
            list = new ArrayList<>(batchCount);
        }
    }
    public void doAfterAllAnalysed(AnalysisContext context) {
        //当数据读取完成后，调用该方法
        //打印操作该集合
        System.out.println("数据条数："+list.size());
        //当数据解析后，将数据一次性全部添加到数据库
        // 12条 3批  5  5 2
        if(list.size() != 0){
            saveData();
        }
    }
    private void saveData(){
        mapper.insertList(list);
    }

    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        System.out.println("发生异常");
        //如果异常是用户输入导致数据异常，提示用户 数据错误
        if(exception instanceof ExcelDataConvertException){
            //提示用户详细信息
            ExcelDataConvertException ex = (ExcelDataConvertException) exception;
            Integer rowIndex = ex.getRowIndex();
            Integer columnIndex = ex.getColumnIndex();
            String value = ex.getCellData().getStringValue();
            throw new RuntimeException("用户提供文件错误:"+value);
        }
        //当异常发生，是否将剩余的数据保存到数据库？
    }

    @Override
    public void invokeHead(Map<Integer, ReadCellData<?>> headMap, AnalysisContext context) {
        //获取表格头信息 map-->list-->ReadCellData-->String-->List<String>
        //List<String> headers = headMap.values()
        //        .stream()
        //        .map(readCellData -> readCellData.getStringValue()).collect(Collectors.toList());
        //System.out.println("表格头信息："+headers);
        Map<Integer, String> map = ConverterUtils.convertToStringMap(headMap, context);
        System.out.println(map);
    }
}
